From 88e557fbdcdf754929c8dcd33f630fc2423971eb Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Tue, 21 Oct 2014 14:48:16 -0400 Subject: [PATCH] Closes #653 Adds a `-q|--quiet` option to all cargo commands that suppresses output from cargo. In the case of `cargo run`, output from the project executable will still be shown. --- src/bin/bench.rs | 4 +- src/bin/build.rs | 4 +- src/bin/cargo.rs | 4 +- src/bin/clean.rs | 4 +- src/bin/doc.rs | 4 +- src/bin/fetch.rs | 4 +- src/bin/generate_lockfile.rs | 4 +- src/bin/git_checkout.rs | 4 +- src/bin/login.rs | 4 +- src/bin/new.rs | 4 +- src/bin/owner.rs | 4 +- src/bin/package.rs | 4 +- src/bin/pkgid.rs | 4 +- src/bin/publish.rs | 4 +- src/bin/run.rs | 5 +- src/bin/rustc.rs | 4 +- src/bin/search.rs | 4 +- src/bin/test.rs | 4 +- src/bin/update.rs | 4 +- src/bin/verify_project.rs | 4 +- src/bin/yank.rs | 4 +- src/cargo/core/mod.rs | 2 +- src/cargo/core/shell.rs | 90 +++++++++++++++++++++++++++--------- src/cargo/lib.rs | 21 +++++---- tests/test_cargo_run.rs | 38 +++++++++++++++ tests/test_shell.rs | 22 +++++++-- 26 files changed, 199 insertions(+), 59 deletions(-) diff --git a/src/bin/bench.rs b/src/bin/bench.rs index ecc8fd686..4b9d5164a 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -12,6 +12,7 @@ struct Options { flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, flag_lib: bool, flag_bin: Vec, flag_example: Vec, @@ -41,6 +42,7 @@ Options: --target TRIPLE Build for the target triple --manifest-path PATH Path to the manifest to build benchmarks for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout All of the trailing arguments are passed to the benchmark binaries generated for filtering benchmarks and generally providing options configuring how they @@ -59,7 +61,7 @@ Compilation can be customized with the `bench` profile in the manifest. pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let ops = ops::TestOptions { no_run: options.flag_no_run, diff --git a/src/bin/build.rs b/src/bin/build.rs index 3af175ec1..0ba089e1b 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -14,6 +14,7 @@ struct Options { flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, flag_release: bool, flag_lib: bool, flag_bin: Vec, @@ -43,6 +44,7 @@ Options: --target TRIPLE Build for the target triple --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output + -q, --quiet No output printed to stdout If the --package argument is given, then SPEC is a package id specification which indicates which package should be built. If it is not given, then the @@ -57,7 +59,7 @@ the --release flag will use the `release` profile instead. pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-build; args={:?}", env::args().collect::>()); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 0e5318b49..73646756d 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -20,6 +20,7 @@ use cargo::util::{CliError, CliResult, lev_distance, Config}; struct Flags { flag_list: bool, flag_verbose: bool, + flag_quiet: bool, arg_command: String, arg_args: Vec, } @@ -36,6 +37,7 @@ Options: -V, --version Print version info and exit --list List installed commands -v, --verbose Use verbose output + -q, --quiet No output printed to stdout Some common cargo commands are: build Compile the current project @@ -89,7 +91,7 @@ macro_rules! each_subcommand{ ($mac:ident) => ({ on this top-level information. */ fn execute(flags: Flags, config: &Config) -> CliResult> { - config.shell().set_verbose(flags.flag_verbose); + try!(config.shell().set_verbosity(flags.flag_verbose, flags.flag_quiet)); init_git_transports(config); diff --git a/src/bin/clean.rs b/src/bin/clean.rs index cc66f29fd..825d05c71 100644 --- a/src/bin/clean.rs +++ b/src/bin/clean.rs @@ -10,6 +10,7 @@ struct Options { flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -24,6 +25,7 @@ Options: --manifest-path PATH Path to the manifest to the package to clean --target TRIPLE Target triple to clean output for (default all) -v, --verbose Use verbose output + -q, --quiet No output printed to stdout If the --package argument is given, then SPEC is a package id specification which indicates which package's artifacts should be cleaned out. If it is not @@ -32,7 +34,7 @@ and its format, see the `cargo help pkgid` command. "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); debug!("executing; cmd=cargo-clean; args={:?}", env::args().collect::>()); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/doc.rs b/src/bin/doc.rs index bd1127e2f..157f3f393 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -12,6 +12,7 @@ struct Options { flag_no_deps: bool, flag_open: bool, flag_verbose: bool, + flag_quiet: bool, flag_package: Option, } @@ -32,6 +33,7 @@ Options: --target TRIPLE Build for the target triple --manifest-path PATH Path to the manifest to document -v, --verbose Use verbose output + -q, --quiet No output printed to stdout By default the documentation for the local package and all dependencies is built. The output is all placed in `target/doc` in rustdoc's usual format. @@ -43,7 +45,7 @@ the `cargo help pkgid` command. "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/fetch.rs b/src/bin/fetch.rs index a5afbf239..3c8ecbdc4 100644 --- a/src/bin/fetch.rs +++ b/src/bin/fetch.rs @@ -6,6 +6,7 @@ use cargo::util::important_paths::find_root_manifest_for_cwd; struct Options { flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -18,6 +19,7 @@ Options: -h, --help Print this message --manifest-path PATH Path to the manifest to fetch dependencies for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout If a lockfile is available, this command will ensure that all of the git dependencies and/or registries dependencies are downloaded and locally @@ -30,7 +32,7 @@ all updated. "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); try!(ops::fetch(&root, config).map_err(|e| { CliError::from_boxed(e, 101) diff --git a/src/bin/generate_lockfile.rs b/src/bin/generate_lockfile.rs index d9777ef66..bb2ade5fe 100644 --- a/src/bin/generate_lockfile.rs +++ b/src/bin/generate_lockfile.rs @@ -8,6 +8,7 @@ use cargo::util::important_paths::find_root_manifest_for_cwd; struct Options { flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -20,11 +21,12 @@ Options: -h, --help Print this message --manifest-path PATH Path to the manifest to generate a lockfile for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-generate-lockfile; args={:?}", env::args().collect::>()); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); ops::generate_lockfile(&root, config) diff --git a/src/bin/git_checkout.rs b/src/bin/git_checkout.rs index 43f62c81d..eaf1df367 100644 --- a/src/bin/git_checkout.rs +++ b/src/bin/git_checkout.rs @@ -7,6 +7,7 @@ struct Options { flag_url: String, flag_reference: String, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -17,10 +18,11 @@ Usage: Options: -h, --help Print this message -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let Options { flag_url: url, flag_reference: reference, .. } = options; let url = try!(url.to_url().map_err(|e| { diff --git a/src/bin/login.rs b/src/bin/login.rs index 16c8f7c85..a0ec4bfea 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -11,6 +11,7 @@ struct Options { flag_host: Option, arg_token: Option, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -23,11 +24,12 @@ Options: -h, --help Print this message --host HOST Host to set the token for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let token = match options.arg_token.clone() { Some(token) => token, None => { diff --git a/src/bin/new.rs b/src/bin/new.rs index fdfb0283e..6c1b6598c 100644 --- a/src/bin/new.rs +++ b/src/bin/new.rs @@ -6,6 +6,7 @@ use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { flag_verbose: bool, + flag_quiet: bool, flag_bin: bool, arg_path: String, flag_name: Option, @@ -27,11 +28,12 @@ Options: --bin Use a binary instead of a library template --name Set the resulting package name -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-new; args={:?}", env::args().collect::>()); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options; diff --git a/src/bin/owner.rs b/src/bin/owner.rs index 38edea893..598555a9a 100644 --- a/src/bin/owner.rs +++ b/src/bin/owner.rs @@ -9,6 +9,7 @@ struct Options { flag_remove: Option>, flag_index: Option, flag_verbose: bool, + flag_quiet: bool, flag_list: bool, } @@ -26,6 +27,7 @@ Options: --index INDEX Registry index to modify owners for --token TOKEN API token to use when authenticating -v, --verbose Use verbose output + -q, --quiet No output printed to stdout This command will modify the owners for a package on the specified registry (or default). Note that owners of a package can upload new versions, yank old @@ -33,7 +35,7 @@ versions, and also modify the set of owners, so take caution! "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let opts = ops::OwnersOptions { krate: options.arg_crate, token: options.flag_token, diff --git a/src/bin/package.rs b/src/bin/package.rs index 444b114fb..828fac3cc 100644 --- a/src/bin/package.rs +++ b/src/bin/package.rs @@ -5,6 +5,7 @@ use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] struct Options { flag_verbose: bool, + flag_quiet: bool, flag_manifest_path: Option, flag_no_verify: bool, flag_no_metadata: bool, @@ -24,11 +25,12 @@ Options: --no-metadata Ignore warnings about a lack of human-usable metadata --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); ops::package(&root, config, !options.flag_no_verify, diff --git a/src/bin/pkgid.rs b/src/bin/pkgid.rs index c5fe8de37..400719e77 100644 --- a/src/bin/pkgid.rs +++ b/src/bin/pkgid.rs @@ -5,6 +5,7 @@ use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] struct Options { flag_verbose: bool, + flag_quiet: bool, flag_manifest_path: Option, arg_spec: Option, } @@ -19,6 +20,7 @@ Options: -h, --help Print this message --manifest-path PATH Path to the manifest to the package to clean -v, --verbose Use verbose output + -q, --quiet No output printed to stdout Given a argument, print out the fully qualified package id specifier. This command will generate an error if is ambiguous as to which package @@ -43,7 +45,7 @@ Example Package IDs pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone())); let spec = options.arg_spec.as_ref().map(|s| &s[..]); diff --git a/src/bin/publish.rs b/src/bin/publish.rs index 224c9a8b6..478947b44 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -8,6 +8,7 @@ struct Options { flag_token: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, flag_no_verify: bool, } @@ -24,11 +25,12 @@ Options: --no-verify Don't verify package tarball before publish --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let Options { flag_token: token, flag_host: host, diff --git a/src/bin/run.rs b/src/bin/run.rs index c34c36be1..dbc0b90ca 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -12,6 +12,7 @@ struct Options { flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, flag_release: bool, arg_args: Vec, } @@ -33,6 +34,7 @@ Options: --target TRIPLE Build for the target triple --manifest-path PATH Path to the manifest to execute -v, --verbose Use verbose output + -q, --quiet No output printed to stdout If neither `--bin` or `--example` are given, then if the project only has one bin target it will be run. Otherwise `--bin` specifies the bin target to run, @@ -43,7 +45,8 @@ All of the trailing arguments are passed as to the binary to run. "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); let (mut examples, mut bins) = (Vec::new(), Vec::new()); diff --git a/src/bin/rustc.rs b/src/bin/rustc.rs index f91c7d89c..ddfca4751 100644 --- a/src/bin/rustc.rs +++ b/src/bin/rustc.rs @@ -15,6 +15,7 @@ struct Options { flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, flag_release: bool, flag_lib: bool, flag_bin: Vec, @@ -44,6 +45,7 @@ Options: --target TRIPLE Target triple which compiles will be for --manifest-path PATH Path to the manifest to fetch depednencies for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout The specified target for the current package (or package specified by SPEC if provided) will be compiled along with all of its dependencies. The specified @@ -60,7 +62,7 @@ must be used to select which target is compiled. pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-rustc; args={:?}", env::args().collect::>()); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/search.rs b/src/bin/search.rs index ee638cc5d..8710f546d 100644 --- a/src/bin/search.rs +++ b/src/bin/search.rs @@ -5,6 +5,7 @@ use cargo::util::{CliResult, CliError, Config}; struct Options { flag_host: Option, flag_verbose: bool, + flag_quiet: bool, arg_query: String } @@ -19,10 +20,11 @@ Options: -h, --help Print this message --host HOST Host of a registry to search in -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let Options { flag_host: host, arg_query: query, diff --git a/src/bin/test.rs b/src/bin/test.rs index 03ce558cf..aafa8ec1c 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -18,6 +18,7 @@ struct Options { flag_test: Vec, flag_bench: Vec, flag_verbose: bool, + flag_quiet: bool, flag_release: bool, } @@ -43,6 +44,7 @@ Options: --target TRIPLE Build for the target triple --manifest-path PATH Path to the manifest to build tests for -v, --verbose Use verbose output + -q, --quiet No output printed to stdout All of the trailing arguments are passed to the test binaries generated for filtering tests and generally providing options configuring how they run. For @@ -63,7 +65,7 @@ Compilation can be configured via the `test` profile in the manifest. pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let ops = ops::TestOptions { no_run: options.flag_no_run, diff --git a/src/bin/update.rs b/src/bin/update.rs index 61df563d3..f1956566b 100644 --- a/src/bin/update.rs +++ b/src/bin/update.rs @@ -11,6 +11,7 @@ struct Options { flag_precise: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -26,6 +27,7 @@ Options: --precise PRECISE Update a single dependency to exactly PRECISE --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output + -q, --quiet No output printed to stdout This command requires that a `Cargo.lock` already exists as generated by `cargo build` or related commands. @@ -50,7 +52,7 @@ For more information about package id specifications, see `cargo help pkgid`. pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-update; args={:?}", env::args().collect::>()); - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); let spec = options.flag_package.as_ref(); diff --git a/src/bin/verify_project.rs b/src/bin/verify_project.rs index 076cfc2db..5b72f0667 100644 --- a/src/bin/verify_project.rs +++ b/src/bin/verify_project.rs @@ -13,6 +13,7 @@ pub type Error = HashMap; struct Flags { flag_manifest_path: String, flag_verbose: bool, + flag_quiet: bool, } pub const USAGE: &'static str = " @@ -24,10 +25,11 @@ Options: -h, --help Print this message --manifest-path PATH Path to the manifest to verify -v, --verbose Use verbose output + -q, --quiet No output printed to stdout "; pub fn execute(args: Flags, config: &Config) -> CliResult> { - config.shell().set_verbose(args.flag_verbose); + try!(config.shell().set_verbosity(args.flag_verbose, args.flag_quiet)); let mut contents = String::new(); let file = File::open(&args.flag_manifest_path); diff --git a/src/bin/yank.rs b/src/bin/yank.rs index 90cf677f1..efd203261 100644 --- a/src/bin/yank.rs +++ b/src/bin/yank.rs @@ -8,6 +8,7 @@ struct Options { flag_vers: Option, flag_index: Option, flag_verbose: bool, + flag_quiet: bool, flag_undo: bool, } @@ -24,6 +25,7 @@ Options: --index INDEX Registry index to yank from --token TOKEN API token to use when authenticating -v, --verbose Use verbose output + -q, --quiet No output printed to stdout The yank command removes a previously pushed crate's version from the server's index. This command does not delete any data, and the crate will still be @@ -35,7 +37,7 @@ crates to be locked to any yanked version. "; pub fn execute(options: Options, config: &Config) -> CliResult> { - config.shell().set_verbose(options.flag_verbose); + try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); try!(ops::yank(config, options.arg_crate, options.flag_vers, diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index cfd3aebdf..f468f8c79 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -5,7 +5,7 @@ pub use self::package_id::{PackageId, Metadata}; pub use self::package_id_spec::PackageIdSpec; pub use self::registry::Registry; pub use self::resolver::Resolve; -pub use self::shell::{Shell, MultiShell, ShellConfig}; +pub use self::shell::{Shell, MultiShell, ShellConfig, Verbosity}; pub use self::source::{Source, SourceId, SourceMap, SourceSet, GitReference}; pub use self::summary::Summary; diff --git a/src/cargo/core/shell.rs b/src/cargo/core/shell.rs index e6e3f49b2..ff5edba10 100644 --- a/src/cargo/core/shell.rs +++ b/src/cargo/core/shell.rs @@ -7,11 +7,21 @@ use term::color::{Color, BLACK, RED, GREEN, YELLOW}; use term::{Terminal, TerminfoTerminal, color}; use self::AdequateTerminal::{NoColor, Colored}; +use self::Verbosity::{Verbose, Normal, Quiet}; + +use util::errors::{human, CargoResult}; + +#[derive(Clone, Copy, PartialEq)] +pub enum Verbosity { + Verbose, + Normal, + Quiet +} #[derive(Clone, Copy)] pub struct ShellConfig { pub color: bool, - pub verbose: bool, + pub verbosity: Verbosity, pub tty: bool } @@ -28,12 +38,12 @@ pub struct Shell { pub struct MultiShell { out: Shell, err: Shell, - verbose: bool + verbosity: Verbosity } impl MultiShell { - pub fn new(out: Shell, err: Shell, verbose: bool) -> MultiShell { - MultiShell { out: out, err: err, verbose: verbose } + pub fn new(out: Shell, err: Shell, verbosity: Verbosity) -> MultiShell { + MultiShell { out: out, err: err, verbosity: verbosity } } pub fn out(&mut self) -> &mut Shell { @@ -45,27 +55,37 @@ impl MultiShell { } pub fn say(&mut self, message: T, color: Color) -> io::Result<()> { - self.out().say(message, color) + match self.verbosity { + Quiet => Ok(()), + _ => self.out().say(message, color) + } } pub fn status(&mut self, status: T, message: U) -> io::Result<()> where T: fmt::Display, U: fmt::Display { - self.out().say_status(status, message, GREEN) + match self.verbosity { + Quiet => Ok(()), + _ => self.out().say_status(status, message, GREEN) + } } pub fn verbose(&mut self, mut callback: F) -> io::Result<()> where F: FnMut(&mut MultiShell) -> io::Result<()> { - if self.verbose { return callback(self) } - Ok(()) + match self.verbosity { + Verbose => return callback(self), + _ => Ok(()) + } } pub fn concise(&mut self, mut callback: F) -> io::Result<()> where F: FnMut(&mut MultiShell) -> io::Result<()> { - if !self.verbose { return callback(self) } - Ok(()) + match self.verbosity { + Verbose => Ok(()), + _ => return callback(self) + } } pub fn error(&mut self, message: T) -> io::Result<()> { @@ -76,12 +96,27 @@ impl MultiShell { self.err().say(message, YELLOW) } + pub fn set_verbosity(&mut self, verbose: bool, quiet: bool) -> CargoResult<()> { + self.verbosity = match (verbose, quiet) { + (true, true) => return Err(human("cannot set both --verbose and --quiet")), + (true, false) => Verbose, + (false, true) => Quiet, + (false, false) => Normal + }; + Ok(()) + } + + /// shortcut for commands that don't have both --verbose and --quiet pub fn set_verbose(&mut self, verbose: bool) { - self.verbose = verbose; + if verbose { + self.verbosity = Verbose; + } else { + self.verbosity = Normal; + } } - pub fn get_verbose(&self) -> bool { - self.verbose + pub fn get_verbose(&self) -> Verbosity { + self.verbosity } } @@ -103,24 +138,33 @@ impl Shell { pub fn verbose(&mut self, mut callback: F) -> io::Result<()> where F: FnMut(&mut Shell) -> io::Result<()> { - if self.config.verbose { return callback(self) } - Ok(()) + match self.config.verbosity { + Verbose => return callback(self), + _ => Ok(()) + } } pub fn concise(&mut self, mut callback: F) -> io::Result<()> where F: FnMut(&mut Shell) -> io::Result<()> { - if !self.config.verbose { return callback(self) } - Ok(()) + match self.config.verbosity { + Verbose => Ok(()), + _ => return callback(self) + } } pub fn say(&mut self, message: T, color: Color) -> io::Result<()> { - try!(self.reset()); - if color != BLACK { try!(self.fg(color)); } - try!(write!(self, "{}\n", message.to_string())); - try!(self.reset()); - try!(self.flush()); - Ok(()) + match self.config.verbosity { + Quiet => Ok(()), + _ => { + try!(self.reset()); + if color != BLACK { try!(self.fg(color)); } + try!(write!(self, "{}\n", message.to_string())); + try!(self.reset()); + try!(self.flush()); + Ok(()) + }, + } } pub fn say_status(&mut self, status: T, message: U, color: Color) diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index fde0b9bc2..33c83add0 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -31,7 +31,8 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_serialize::json::{self, Json}; use docopt::Docopt; -use core::{Shell, MultiShell, ShellConfig}; +use core::{Shell, MultiShell, ShellConfig, Verbosity}; +use core::shell::Verbosity::{Verbose}; use term::color::{BLACK, RED}; pub use util::{CargoError, CliError, CliResult, human, Config, ChainError}; @@ -95,7 +96,7 @@ fn process(mut callback: F) { let mut config = None; let result = (|| { - config = Some(try!(Config::new(shell(true)))); + config = Some(try!(Config::new(shell(Verbose)))); let args: Vec<_> = try!(env::args_os().map(|s| { s.into_string().map_err(|s| { human(format!("invalid unicode in argument: {:?}", s)) @@ -103,7 +104,7 @@ fn process(mut callback: F) }).collect()); callback(&args, config.as_ref().unwrap()) })(); - let mut verbose_shell = shell(true); + let mut verbose_shell = shell(Verbose); let mut shell = config.as_ref().map(|s| s.shell()); let shell = shell.as_mut().map(|s| &mut **s).unwrap_or(&mut verbose_shell); process_executed(result, shell) @@ -122,20 +123,20 @@ pub fn process_executed(result: CliResult>, shell: &mut MultiShell) } } -pub fn shell(verbose: bool) -> MultiShell { +pub fn shell(verbosity: Verbosity) -> MultiShell { let tty = isatty(libc::STDERR_FILENO); let stderr = Box::new(io::stderr()); - let config = ShellConfig { color: true, verbose: verbose, tty: tty }; + let config = ShellConfig { color: true, verbosity: verbosity, tty: tty }; let err = Shell::create(stderr, config); let tty = isatty(libc::STDOUT_FILENO); let stdout = Box::new(io::stdout()); - let config = ShellConfig { color: true, verbose: verbose, tty: tty }; + let config = ShellConfig { color: true, verbosity: verbosity, tty: tty }; let out = Shell::create(stdout, config); - return MultiShell::new(out, err, verbose); + return MultiShell::new(out, err, verbosity); #[cfg(unix)] fn isatty(fd: libc::c_int) -> bool { @@ -173,7 +174,7 @@ pub fn handle_error(err: CliError, shell: &mut MultiShell) { let fatal = exit_code != 0; // exit_code == 0 is non-fatal error - let hide = unknown && !shell.get_verbose(); + let hide = unknown && shell.get_verbose() != Verbose; if hide { let _ = shell.err().say("An unknown error occurred", RED); } else { @@ -195,12 +196,12 @@ fn handle_cause(mut cargo_err: &CargoError, shell: &mut MultiShell) -> bool { Some(cause) => cause, None => { err = cargo_err.cause(); break } }; - if !verbose && !cargo_err.is_human() { return false } + if verbose != Verbose && !cargo_err.is_human() { return false } print(cargo_err.to_string(), shell); } loop { let cause = match err { Some(err) => err, None => return true }; - if !verbose { return false } + if verbose != Verbose { return false } print(cause.to_string(), shell); err = cause.cause(); } diff --git a/tests/test_cargo_run.rs b/tests/test_cargo_run.rs index 9275ce380..d0f494520 100644 --- a/tests/test_cargo_run.rs +++ b/tests/test_cargo_run.rs @@ -32,6 +32,44 @@ hello assert_that(&p.bin("foo"), existing_file()); }); +test!(simple_quiet { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/main.rs", r#" + fn main() { println!("hello"); } + "#); + + assert_that(p.cargo_process("run").arg("-q"), + execs().with_status(0).with_stdout("\ +hello +") + ); +}); + +test!(simple_quiet_and_verbose { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/main.rs", r#" + fn main() { println!("hello"); } + "#); + + assert_that(p.cargo_process("run").arg("-q").arg("-v"), + execs().with_status(101).with_stderr("\ +cannot set both --verbose and --quiet +") + ); +}); + test!(simple_with_args { let p = project("foo") .file("Cargo.toml", r#" diff --git a/tests/test_shell.rs b/tests/test_shell.rs index a325165e8..630a74d09 100644 --- a/tests/test_shell.rs +++ b/tests/test_shell.rs @@ -4,7 +4,8 @@ use std::sync::{Arc, Mutex}; use term::{Terminal, TerminfoTerminal, color}; use hamcrest::{assert_that}; -use cargo::core::shell::{Shell,ShellConfig}; +use cargo::core::shell::{Shell, ShellConfig}; +use cargo::core::shell::Verbosity::{Verbose, Quiet}; use support::{Tap, shell_writes}; @@ -21,7 +22,7 @@ impl Write for Sink { } test!(non_tty { - let config = ShellConfig { color: true, verbose: true, tty: false }; + let config = ShellConfig { color: true, verbosity: Verbose, tty: false }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -33,7 +34,7 @@ test!(non_tty { }); test!(color_explicitly_disabled { - let config = ShellConfig { color: false, verbose: true, tty: true }; + let config = ShellConfig { color: false, verbosity: Verbose, tty: true }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -47,7 +48,7 @@ test!(colored_shell { let term = TerminfoTerminal::new(Vec::new()); if term.is_none() { return } - let config = ShellConfig { color: true, verbose: true, tty: true }; + let config = ShellConfig { color: true, verbosity: Verbose, tty: true }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -59,6 +60,19 @@ test!(colored_shell { color::RED).unwrap())); }); +test!(quiet_shell { + let config = ShellConfig { color: true, verbosity: Quiet, tty: true }; + let a = Arc::new(Mutex::new(Vec::new())); + + Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { + shell.say("Should be suppressed", color::BLACK).unwrap(); + }); + + let buf = a.lock().unwrap().clone(); + assert_that(&buf[..], + shell_writes("")); +}); + fn colored_output(string: &str, color: color::Color) -> io::Result { let mut term = TerminfoTerminal::new(Vec::new()).unwrap(); try!(term.reset()); -- 2.30.2